package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import com.aliyun.gts.bpaas.framework.api.rest.dto.ResultResponse;
import com.aliyun.gts.delivery.enterprise.sdk.rbac.RbacService;
import com.aliyun.gts.delivery.enterprise.sdk.rbac.in.AccountPermissionQuery;
import com.aliyun.gts.delivery.enterprise.sdk.rbac.in.AccountRoleQuery;
import com.aliyun.gts.delivery.enterprise.sdk.rbac.out.Permission;
import com.aliyun.gts.delivery.enterprise.sdk.rbac.out.Role;
import com.aliyun.gts.enterprise.basic.RbacBasicAuthService;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.UserEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.properties.MenuAuthProperties;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.User;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.UserRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

/**
 * @author lilh
 * @date 2020/11/19 下午1:57
 */
@Service
@EnableConfigurationProperties(MenuAuthProperties.class)
public class RbacServiceAdapter implements InitializingBean {

    @Autowired
    private MenuAuthProperties menuAuthProperties;

    @Autowired(required = false)
    private RbacService delegate;

    @Autowired
    private UserRepository userRepository;

    /**
     * nacos上刷新配置后，可实时生效
     */
    private Map<UserEnum, Supplier<Set<String>>> roleToMenuAuthMap = new HashMap<>();


    public ResultResponse<Role> getRoleByCode(String s) {
        return delegate.getRoleByCode(s);
    }

    public ResultResponse<Permission> getPermissionByCode(String s) {
        return delegate.getPermissionByCode(s);
    }

    public ResultResponse<List<Permission>> queryPermissionByRoleCode(String s) {
        return delegate.queryPermissionByRoleCode(s);
    }

    public ResultResponse<List<Role>> queryRoleByAccountCode(AccountRoleQuery accountRoleQuery) {
        return delegate.queryRoleByAccountCode(accountRoleQuery);
    }

    public ResultResponse<Boolean> hasRole(AccountRoleQuery accountRoleQuery) {
        return delegate.hasRole(accountRoleQuery);
    }

    public ResultResponse<Boolean> hasPermission(AccountPermissionQuery accountPermissionQuery) {
        return delegate.hasPermission(accountPermissionQuery);
    }

    public ResultResponse<List<Permission>> getPermissionByAccountCode(String s) {
        return delegate.getPermissionByAccountCode(s);
    }


    public Set<String> getCurrentUserMenuResource() {
        User current = userRepository.getCurrentUser();
        UserEnum userType = UserEnum.getUser(current.getUserType());
        if (Objects.isNull(userType)) {
            userType = UserEnum.NORMAL;
        }
        return roleToMenuAuthMap.get(userType).get();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        roleToMenuAuthMap.put(UserEnum.SUPER, () -> menuAuthProperties.getSuperUserMenus());
        roleToMenuAuthMap.put(UserEnum.TENANT, () -> menuAuthProperties.getTenantUserMenus());
        roleToMenuAuthMap.put(UserEnum.NORMAL, () -> menuAuthProperties.getNormalUserMenus());
        if (Objects.isNull(delegate)) {
            this.delegate = new RbacBasicAuthService();
        }
    }
}
